<template>
  <el-drawer v-model="visible" title="脚本库" size="80%" :destroy-on-close="false">
    <div class="script-library">
      <!-- 顶部控制区 -->
      <div class="controls">
        <el-button type="primary" size="small" @click="showCreateDialog">
          创建脚本
        </el-button>
      </div>

      <!-- 表格区域 -->
      <div class="table-container">
        <table class="threats-table">
          <thead>
            <tr>
              <th>名称</th>
              <th>执行目录</th>
              <th>备注</th>
              <th>创建时间</th>
              <th>操作</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="script in scripts" :key="script.id">
              <td>{{ script.name }}</td>
              <td>{{ script.execute_directory }}</td>
              <td>{{ script.remark }}</td>
              <td>{{ script.created_at }}</td>
              <td>
                <el-button size="small" type="primary" @click="handleExecute(script)" style="margin-right: 4px;">
                  执行
                </el-button>
                <el-button size="small" type="warning" @click="handleEdit(script)" style="margin-right: 4px;">
                  编辑
                </el-button>
                <el-button size="small" type="danger" @click="handleDelete(script)">
                  删除
                </el-button>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>

    <!-- 创建/编辑脚本表单弹窗 -->
    <el-dialog v-model="formDialog.visible" :title="formDialog.isEdit ? '编辑脚本' : '创建脚本'" width="500px"
      :close-on-click-modal="false">
      <el-form ref="formRef" :model="formDialog.form" :rules="formRules" label-width="100px">
        <el-form-item label="名称" prop="name">
          <el-input v-model="formDialog.form.name" />
        </el-form-item>
        <el-form-item label="执行目录" prop="directory">
          <el-input v-model="formDialog.form.directory" style="max-width: 600px" placeholder="请选择执行命令的目录"
            class="input-with-select">
            <template #append>
              <el-button :icon="Folder" @click="selectDirectory" />
            </template>
          </el-input>
        </el-form-item>
        <el-form-item label="执行命令" prop="command">
          <el-input v-model="formDialog.form.command" />
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input v-model="formDialog.form.remark" type="textarea" :rows="3" />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="formDialog.visible = false">取消</el-button>
          <el-button type="primary" @click="handleSubmit">确定</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 删除确认弹窗 -->
    <el-dialog v-model="deleteDialog.visible" title="确认删除" width="300px">
      <p>确定要删除该脚本吗？</p>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="deleteDialog.visible = false">取消</el-button>
          <el-button type="danger" @click="confirmDelete">确定</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 目录选择对话框 -->
    <el-dialog v-model="directoryDialog.visible" title="选择文件" width="60%">
      <div class="directory-dialog">
        <div class="path-bar">
          <el-button :icon="Back" class="back-button" @click="removeBreadcrumbItem" />
          <el-breadcrumb separator="/" class="path-bar-breadcrumb">
            <el-breadcrumb-item v-for="(item, index) in breadcrumbItems" :key="index" @click="removeAfterItem(index)"
              style="cursor: pointer;">
              {{ item }}
            </el-breadcrumb-item>
          </el-breadcrumb>
          <el-button :icon="Refresh" class="refresh-button" @click="refreshDirectory" />
        </div>
        <div class="directory-list">
          <el-table :data="directoryDialog.directories" style="width: 100%">
            <el-table-column label="名称">
              <template #default="{ row }">
                <span v-if="row.is_folder" @click="handleFolderClick(row)"
                  style="cursor: pointer; display: flex; align-items: center;">
                  <Folder style="margin-right: 4px;width: 20px;" />
                  {{ row.name }}
                </span>
                <span v-else>
                  {{ row.name }}
                </span>
              </template>
            </el-table-column>
            <el-table-column prop="modified_time" label="修改时间" />
            <el-table-column prop="permissions" label="权限/所有者" />
          </el-table>
        </div>
      </div>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="handleDirectorySelect">确定</el-button>
          <el-button @click="directoryDialog.visible = false">取消</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 执行脚本弹窗 -->
    <el-dialog v-model="executeDialog.visible" title="执行脚本" width="50%" :close-on-click-modal="false">
      <div class="execute-content">
        <div class="log-output">
          <!-- 这里可以动态显示执行日志 -->
          <p v-for="log in logData" :key="log">{{ log }}</p>
        </div>
      </div>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="executeDialog.visible = false">关闭</el-button>
        </div>
      </template>
    </el-dialog>
  </el-drawer>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, watch } from 'vue'
import type { Script, ScriptForm } from '@/types/script'
import { ElMessage } from 'element-plus'
import type { FormInstance } from 'element-plus'
import { Back, Refresh, Folder } from '@element-plus/icons-vue'
import { API_URL, WS_URL } from '@/utils/config'
import axios from 'axios'

const props = defineProps({
  modelValue: {
    type: Boolean,
    required: true
  }
})

const emit = defineEmits(['update:modelValue'])

// 控制抽屉显示
const visible = computed({
  get: () => props.modelValue,
  set: (val) => emit('update:modelValue', val)
})

// 脚本列表数据
const scripts = ref<Script[]>([])

// 表单对话框
const formDialog = ref({
  visible: false,
  isEdit: false,
  form: {
    name: '',
    directory: '',
    command: '',
    remark: '',
    id: 0,
  } as ScriptForm,
  currentId: null as number | null
})

// 删除对话框
const deleteDialog = ref({
  visible: false,
  currentScript: null as Script | null
})

// 表单规则
const formRules = {
  name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
  directory: [{ required: true, message: '请输入执行目录', trigger: 'blur' }],
  command: [{ required: true, message: '请输入执行命令', trigger: 'blur' }]
}

const formRef = ref<FormInstance>()

// 文件选择对话框
const directoryDialog = ref({
  visible: false,
  // currentPath: '/www/wwwroot',
  currentPath: '/Users/drip',
  directories: [] as {
    name: string,
    modified_time: string,
    permissions: string,
    is_folder: boolean
  }[]
})

// 选择目录方法
const selectDirectory = async () => {
  directoryDialog.value.visible = true
  try {
    const response = await axios.post(`${API_URL}/files/get_dir`, {
      path: directoryDialog.value.currentPath
    })

    directoryDialog.value.directories = response.data.data.files || []
  } catch (error) {
    ElMessage.error('获取目录列表失败')
  }
}

// 选择具体目录
const handleDirectorySelect = () => {
  formDialog.value.form.directory = directoryDialog.value.currentPath
  directoryDialog.value.visible = false
}

// 显示创建对话框
const showCreateDialog = () => {
  formDialog.value.isEdit = false
  formDialog.value.form = {
    name: '',
    directory: '',
    command: '',
    remark: '',
    id: 0
  }
  formDialog.value.visible = true
}

// 处理编辑
const handleEdit = (script: Script) => {
  formDialog.value.isEdit = true
  formDialog.value.currentId = script.id
  formDialog.value.form = {
    name: script.name,
    directory: script.execute_directory,
    command: script.command,
    remark: script.remark,
    id: script.id
  }
  formDialog.value.visible = true
}

// 处理删除
const handleDelete = async (script: Script) => {
  deleteDialog.value.currentScript = script
  deleteDialog.value.visible = true
}

// 确认删除
const confirmDelete = async () => {
  const scriptId = deleteDialog.value.currentScript?.id
  if (!scriptId) {
    ElMessage.error("缺少脚本ID")
  }
  try {
    // TODO: 调用删除 API
    const response = await axios.delete(`${API_URL}/script/${scriptId}`)
    const code = response.data.code
    const msg = response.data.msg
    if (code == 0) {
      ElMessage.success('删除成功')
    } else {
      ElMessage.error(msg)
    }

    deleteDialog.value.visible = false
    await fetchScripts()
  } catch (error) {
    ElMessage.error('删除失败')
  }
}

// 处理执行
const handleExecute = async (script: Script) => {
  executeDialog.value.currentScript = script
  executeDialog.value.visible = true

  const scriptId = script.id
  if (!scriptId) {
    ElMessage.error("缺少脚本ID")
    return
  }
  try {
    // TODO: 调用删除 API
    const response = await axios.get(`${API_URL}/script/${scriptId}/command/${uuserId}`)
    const code = response.data.code
    const msg = response.data.msg
    if (code == 0) {
      ElMessage.success('执行成功')
    } else {
      ElMessage.error(msg)
    }

    deleteDialog.value.visible = false
    // await fetchScripts()
  } catch (error) {
    ElMessage.error('执行失败')
  }
}

// 提交表单
const handleSubmit = async () => {
  if (!formRef.value) return

  await formRef.value.validate(async (valid) => {
    if (valid) {
      try {
        if (formDialog.value.isEdit) {
          const response = await axios.put(`${API_URL}/script`, {
            name: formDialog.value.form.name,
            directory: formDialog.value.form.directory,
            command: formDialog.value.form.command,
            remark: formDialog.value.form.remark,
            id: formDialog.value.form.id
          })
          const code = response.data.code
          const msg = response.data.msg
          if (code == 0) {
            ElMessage.success('更新成功')
          } else {
            ElMessage.error(msg)
          }

        } else {
          const response = await axios.post(`${API_URL}/script`, {
            name: formDialog.value.form.name,
            directory: formDialog.value.form.directory,
            command: formDialog.value.form.command,
            remark: formDialog.value.form.remark,
          })
          const code = response.data.code
          const msg = response.data.msg
          if (code == 0) {
            ElMessage.success('创建成功')
          } else {
            ElMessage.error(msg)
          }
        }
        formDialog.value.visible = false
        await fetchScripts()
      } catch (error) {
        ElMessage.error(formDialog.value.isEdit ? '更新失败' : '创建失败')
      }
    }
  })
}

// 获取脚本列表
const fetchScripts = async () => {
  try {
    // TODO: 调用获取脚本列表 API
    const response = await axios.get(`${API_URL}/script`)
    scripts.value = response.data.data.items || []
  } catch (error) {
    ElMessage.error('获取脚本列表失败')
  }
}

// WebSocket connection for real-time log updates
const logData = ref<string[]>([]);
const uuserId = Date.now().toString()

// 初始化
const wsCode = () => {
  var uid = 'user' + Date.now()
  // var uname = prompt('请输入用户名', 'user' + 100);

  const socket = new WebSocket(`${WS_URL}/ws`); // Replace with your WebSocket URL
  socket.onopen = function () {
    ElMessage.success('WebSocket连接成功')
    var msg = { 'content': Date.now().toString(), 'type': 'user', 'userId': uuserId };
    sendMsg(msg)
      
    setInterval(() => {
      var msg = { 'content': 'pong', 'type': 'ping' };
      sendMsg(msg)
    }, 10000);
  }
  socket.onmessage = function (e) {
    var msg = JSON.parse(e.data);
    switch (msg.type) { // TODO 暂时做一下类型的区分，但没有实现具体的业务逻辑
      case 'system':
        break;
    }
    logData.value.push(msg.content);
  };
  socket.onerror = function () {
    var data = "系统消息 : 出错了,请退出重试.";
    ElMessage.error(data)
  };
  const send = () => {
    var msg_box = document.getElementById("msg_box");
    var content = msg_box.value;
    var reg = new RegExp("\r\n", "g");
    content = content.replace(reg, "");
    var msg = { 'content': content.trim(), 'type': 'user' };
    sendMsg(msg);
    msg_box.value = '';
  }
  const sendMsg = (msg) => {
    var data = JSON.stringify(msg);
    socket.send(data);
  }

  // socket.addEventListener('message', (event) => {
  //   const message = event.data;
  //   logData.value.push(message);
  // });

  // socket.addEventListener('error', (error) => {
  //   console.error('WebSocket error:', error);
  //   ElMessage.error('WebSocket连接失败');
  // });

  // socket.addEventListener('close', () => {
  //   console.log('WebSocket connection closed');
  // });
}

// 面包屑
// const breadcrumbItems = ref(['根目录', 'www', 'wwwroot'])
const breadcrumbItems = ref(['根目录', 'Users', 'drip'])

// 点击后退按钮移除元素
const removeBreadcrumbItem = async () => {
  if (breadcrumbItems.value.length > 1) {
    breadcrumbItems.value.pop()
    directoryDialog.value.currentPath = breadcrumbItems.value.join('/').replace('根目录', '')
  }
  if (breadcrumbItems.value.length == 1) {
    directoryDialog.value.currentPath = '/'
  }
  const response = await axios.post(`${API_URL}/files/get_dir`, {
    path: directoryDialog.value.currentPath
  })

  directoryDialog.value.directories = response.data.data.files || []
}

const removeAfterItem = async (index: number) => {
  breadcrumbItems.value = breadcrumbItems.value.slice(0, index + 1)
  directoryDialog.value.currentPath = breadcrumbItems.value.join('/').replace('根目录', '')
  if (breadcrumbItems.value.length == 1) {
    directoryDialog.value.currentPath = '/'
  }
  const response = await axios.post(`${API_URL}/files/get_dir`, {
    path: directoryDialog.value.currentPath
  })

  directoryDialog.value.directories = response.data.data.files || []
}

// 刷新目录
const loading = ref(false)

const refreshDirectory = async () => {
  loading.value = true
  try {
    const response = await axios.post(`${API_URL}/files/get_dir`, {
      path: directoryDialog.value.currentPath
    })

    directoryDialog.value.directories = response.data.data.files || []
  } catch (error) {
    ElMessage.error('获取目录列表失败')
  } finally {
    loading.value = false
  }
}

// 处理文件夹点击
const handleFolderClick = async (row: { name: string }) => {
  breadcrumbItems.value.push(row.name)
  directoryDialog.value.currentPath = breadcrumbItems.value.join('/').replace('根目录', '')

  try {
    const response = await axios.post(`${API_URL}/files/get_dir`, {
      path: directoryDialog.value.currentPath
    })

    directoryDialog.value.directories = response.data.data.files || []
  } catch (error) {
    ElMessage.error('获取目录列表失败')
    // 如果获取失败，回退面包屑
    breadcrumbItems.value.pop()
    directoryDialog.value.currentPath = breadcrumbItems.value.join('/').replace('根目录', '')
  }
}

watch(visible, (newVal) => {
  if (newVal) {
    fetchScripts();

    // 开启WebSocket，并实现消息发送和接收
    wsCode()
  }
});

const executeDialog = ref({
  visible: false,
  currentScript: null as Script | null
})
</script>

<style scoped>
.script-library {
  padding: 16px;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.controls {
  margin-bottom: 16px;
}

.table-container {
  flex: 1;
  overflow-y: auto;
}

.threats-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

.threats-table th,
.threats-table td {
  padding: 8px;
  border: 1px solid #e0e0e0;
  text-align: left;
}

.threats-table th {
  background-color: #f5f5f5;
  font-weight: normal;
  color: #666;
}

.threats-table tbody tr:nth-child(even) {
  background-color: #fafafa;
}

.threats-table tbody tr:hover {
  background-color: #f0f0f0;
}

:deep(.el-button--small) {
  padding: 4px 12px;
  font-size: 12px;
}

.directory-dialog {
  .path-bar {
    margin-bottom: 16px;
  }

  .directory-list {
    height: 400px;
    overflow-y: auto;
  }
}

.path-bar {
  display: flex;
  width: 100%;
  overflow-x: hidden;
}

.el-breadcrumb {
  border-bottom: solid 1px #dcdfe6;
  border-top: solid 1px #dcdfe6;
  height: 30px;
  line-height: 30px;
  width: 100%;
  padding: 0 10px 0 10px;
  overflow-x: scroll;
  white-space: nowrap;
}

.back-button {
  border-radius: 4px 0 0 4px;
}

.refresh-button {
  border-radius: 0 4px 4px 0;
}

el-breadcrumb-item {
  cursor: pointer;
}

.execute-content {
  background-color: #000;
  color: #fff;
  height: 400px;
  overflow-y: auto;
  padding: 16px;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
}
</style>
